package com.mediaideas.videoengine;

import android.app.Service;
import android.content.Intent;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.RemoteException;
import android.util.Log;

import com.mediaideas.videoengine.constants.AppMessageDef;

import java.lang.ref.WeakReference;

/**
 * Created by Jonathan Kranz on 2016/3/9.
 * 混音Service, 最好做为单独的一个进程,规避因混音service崩溃不至于导致整个app崩溃
 */
public class AudioMixerService extends Service {
    protected final static String TAG = "AudioMixerService";
    // serviceID 方便stopself处理
    protected int mServiceStartId = -1;
    // 标识service是否处于bind状态
    protected boolean mServiceInUse = false;
    // 音频处理对象句柄
    protected AudioProc mAudioProc;
    // 音频混音参数对象
    protected AudioMixerParams mAudioMixerParams;
    // 音频混音回调接口
    protected IAudioMixerStatusCallback mCallback;
    protected Handler mHandler = new MsgHandler(this);
    // 对外接口对象,实现了IAudioMixerService.AIDL接口
    protected IBinder mBinder = new AudioMixerServiceStub(this);

    public AudioMixerService() {

    }

    @Override
    public void onCreate() {
        super.onCreate();
        mAudioProc = new AudioProc(getApplicationContext(), mHandler);
        Log.e(TAG, "AudioMixerService created");
    }

    @Override
    public IBinder onBind(Intent intent) {
        mServiceInUse = true;
        Log.e(TAG, "on Bind");
        return mBinder;
    }

    @Override
    public void onRebind(Intent intent) {
        mServiceInUse = true;
        Log.e(TAG, "on Rebind");
    }

    @Override
    public boolean onUnbind(Intent intent) {
        mServiceInUse = false;
        stopSelf(mServiceStartId);
        Log.e(TAG, "on Unbind");
        return true;
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        mServiceStartId = startId;
        Log.e(TAG, "on start command");
//        return START_STICKY;
        return Service.START_NOT_STICKY;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.e(TAG, "AudioMixerService destroy");
    }

    // 获取AudioMixer进程ID
    protected int getAudioMixerServicePid() {
        return android.os.Process.myPid();
    }
    // 获取混音处理状态
    protected int getAudioProcessStatus() {
        boolean result = mAudioProc.getSavingStatus();
        return result ? AudioProc.STATUS_AUDIO_PROC_SAVING : AudioProc.STATUS_AUDIO_PROC_SUCCESS;
    }
    // 返回混音service是否处于bind状态
    protected boolean hasUseAudioMixerService() {
        return mServiceInUse;
    }

    // 启动混音处理线程-调用JNI方法处理
    protected int startAudioMixer(final AudioMixerParams params) {
        mAudioMixerParams = params;
        new Thread(new Runnable() {
            @Override
            public void run() {
                mAudioProc.startConvertAudio(params);
            }
        }).start();
        return 0;
    }

    // 取消混音处理-调用JNI方法取消
    protected int cancelAudioMixer() {
        return mAudioProc.cancelConvertAudio();
    }

    // 销毁混音处理分配的底层资源-调用JNI方法处理
    protected int destroy() {
        return mAudioProc.destroy();
    }
    // 设置混音状态回调接口
    protected void setAudioMixerStatusCallback(IAudioMixerStatusCallback callback) {
        mCallback = callback;
    }
    // 移除混音状态回调接口
    protected void removeAudioMixerStatusCallback() {
        mCallback = null;
    }
    // 处理混音进度及混音结构
    protected static class MsgHandler extends Handler {
        WeakReference<AudioMixerService> reference;

        public MsgHandler(AudioMixerService audioMixerService) {
            reference = new WeakReference<AudioMixerService>(audioMixerService);
        }

        @Override
        public void handleMessage(Message msg) {
            IAudioMixerStatusCallback callback = reference.get().mCallback;
            if (callback == null) {
                return;
            }
            switch (msg.what) {
                // 混音进度,通过AIDL回调接口返回上层处理
                case AppMessageDef.MSG_JNI_CALLBACK_NOTIFY_PROGRESS:
                    try {
                        callback.onAudioMixerProgress(msg.arg1);
                    } catch (RemoteException e) {
                        e.printStackTrace();
                    }
                    break;
                // 混音结构,通过AIDL回调接口返回上层处理
                case AppMessageDef.MSG_JNI_CALLBACK_NOTIFY_RESULT:
                    String path = reference.get().mAudioMixerParams.getDstAudioFilePath();
                    try {
                        callback.onFinishedAudioMixer(msg.arg1, path);
                    } catch (RemoteException e) {
                        e.printStackTrace();
                    }
                    break;
            }
            super.handleMessage(msg);
        }
    }

    // 对外接口通信类
    protected static class AudioMixerServiceStub extends IAudioMixerService.Stub {
        WeakReference<AudioMixerService> reference;

        public AudioMixerServiceStub(AudioMixerService audioMixerService) {
            reference = new WeakReference<AudioMixerService>(audioMixerService);
        }

        /**
         * 获取混音服务的进程ID
         *
         * @return
         * @throws RemoteException
         */
        @Override
        public int getAudioMixerServicePid() throws RemoteException {
            return reference.get().getAudioMixerServicePid();
        }

        @Override
        public int getAudioProcessStatus() throws RemoteException {
            return reference.get().getAudioProcessStatus();
        }

        /**
         * 混音服务 是否启用
         *
         * @return
         * @throws RemoteException
         */
        @Override
        public boolean hasUseAudioMixerService() throws RemoteException {
            return reference.get().hasUseAudioMixerService();
        }

        /**
         * 开始混音
         *
         * @param params
         * @return
         * @throws RemoteException
         */
        @Override
        public int startAudioMixer(AudioMixerParams params) throws RemoteException {
            return reference.get().startAudioMixer(params);
        }

        /**
         * 取消混音
         *
         * @return
         * @throws RemoteException
         */
        @Override
        public int cancelAudioMixer() throws RemoteException {
            return reference.get().cancelAudioMixer();
        }

        /**
         * 销毁混音服务
         *
         * @return
         * @throws RemoteException
         */
        @Override
        public int destory() throws RemoteException {
            return reference.get().destroy();
        }

        /**
         * 设置混音状态回调
         *
         * @param callback
         * @throws RemoteException
         */
        @Override
        public void setAudioMixerStatusCallback(IAudioMixerStatusCallback callback) throws RemoteException {
            reference.get().setAudioMixerStatusCallback(callback);
        }

        /**
         * 移除混音状态回调
         *
         * @throws RemoteException
         */
        @Override
        public void removeAudioMixerStatusCallback() throws RemoteException {
            reference.get().removeAudioMixerStatusCallback();
        }
    }
}
